package proceso;

import java.io.File;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Locale;
import java.util.Map;
import javax.swing.JFrame;
import javax.swing.JButton;
import javax.swing.JLabel;
import javax.swing.JTextField;
import net.sf.jasperreports.engine.JRException;
import net.sf.jasperreports.engine.JRParameter;
import net.sf.jasperreports.engine.JasperFillManager;
import net.sf.jasperreports.engine.JasperPrint;
import net.sf.jasperreports.engine.JasperReport;
import net.sf.jasperreports.engine.export.JRXlsExporterParameter;
import net.sf.jasperreports.engine.export.ooxml.JRXlsxExporter;
import net.sf.jasperreports.engine.util.JRLoader;
import util.Conexion;
import java.awt.event.ActionListener;
import java.awt.event.ActionEvent;

public class Proceso extends JFrame{
	private static final long serialVersionUID = 1L;
	File fileO = null;
	String fileD = "";
	ArrayList<String> negativos = new ArrayList<String>();
	ArrayList<String> resultados = new ArrayList<String>();
	private JButton btnProcesar;
	private JTextField txtEjercicio;
	private JTextField txtPeriodo;
	private JLabel lblPeriodo;
	private JLabel lblEjercicio;
	TextFilterDocument tfdEjercicio = new TextFilterDocument(TextFilterDocument.DIGITS,4);
	TextFilterDocument tfdPeriodo = new TextFilterDocument(TextFilterDocument.DIGITS,2);
	private JLabel lblEtiqueta;
	
	public Proceso() {
		setVisible(true);
		setSize(283, 126);
		setLocationRelativeTo(null);
		setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
		getContentPane().setLayout(null);
		
		btnProcesar = new JButton("Procesar");
		btnProcesar.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent e) {
				try {
					String ejercicio = txtEjercicio.getText().trim();
					String periodo = txtPeriodo.getText().trim();
					if(!ejercicio.equals("") && !periodo.equals("")){
						Conexion.conectar();
						if(existe(ejercicio, periodo)>0){
							if(periodo.length()==2){
								reconstruirSaldo(ejercicio,periodo);
								exportar();
							}else{
								Sesion.mensajeError(null, "El formato para el periodo es de 2 digitos");
							}
						}else{
							Sesion.mensajeInformacion(null, "No existen resultados para el ejercicio y periodo ingresado");
						}
						Conexion.desconectar();
						System.gc();
					}
				} catch (SQLException e1) {
					Sesion.mensajeInformacion(null, "Error SQL:"+e1.getMessage());
				} catch (OutOfMemoryError e1) {
					Sesion.mensajeInformacion(null, "Error por falta de memoria");
				} catch (Exception e1) {
					Sesion.mensajeInformacion(null, "Error " + e1.getMessage());
				}
			}
		});
		btnProcesar.setBounds(146, 10, 111, 23);
		getContentPane().add(btnProcesar);
		
		txtEjercicio = new JTextField();
		txtEjercicio.setBounds(81, 11, 52, 20);
		txtEjercicio.setDocument(tfdEjercicio);
		getContentPane().add(txtEjercicio);
		
		txtPeriodo = new JTextField();
		txtPeriodo.setBounds(81, 42, 36, 20);
		txtPeriodo.setDocument(tfdPeriodo);
		getContentPane().add(txtPeriodo);
		
		lblEjercicio = new JLabel("Ejercicio:");
		lblEjercicio.setBounds(10, 14, 61, 14);
		getContentPane().add(lblEjercicio);
		
		lblPeriodo = new JLabel("Periodo:");
		lblPeriodo.setBounds(10, 45, 61, 14);
		getContentPane().add(lblPeriodo);
		
		lblEtiqueta = new JLabel("");
		lblEtiqueta.setBounds(10, 70, 247, 14);
		getContentPane().add(lblEtiqueta);
		
	}
	
	private int existe(String ejercicio,String periodo) throws SQLException{
		PreparedStatement pstm = Conexion.obtenerConexion().prepareStatement("select count(*) from speed400tc.tmovd where mdejer=? and mdperi=?");
		pstm.setInt(1,Integer.parseInt(ejercicio));
		pstm.setInt(2,Integer.parseInt(periodo));
		ResultSet rs = pstm.executeQuery();
		int resultado=0;
		rs.next();
		resultado = rs.getInt(1);
		rs.close();
		pstm.close();
		return resultado;
	}
	
	private void reconstruirSaldo(String ejercicio,String periodo) throws SQLException {
		PreparedStatement pstm = Conexion.obtenerConexion().prepareStatement("delete from prodtecni.tsalmtemp");
		pstm.executeUpdate();
		pstm.close();
	
		PreparedStatement pstm2 = Conexion.obtenerConexion().prepareStatement("insert into prodtecni.tsalmtemp(mdalmt,mdcoat,mdcant,mdsitu) " +
				"select mdalma,mdcoar,sum(case when mdcmov='I' then mdcanr when mdcmov='S' then mdcanr* - 1 end ),'00' from speed400tc.tmovd where  mdejer|| right('0'||mdperi,2)<"+ejercicio+periodo+" group by mdalma,mdcoar ");
		pstm2.executeUpdate();
		pstm2.close();
		
		PreparedStatement pstm3 = Conexion.obtenerConexion().prepareStatement("insert into prodtecni.tsalmtemp(mdcoat,mdalmt,mdcant,mdsitu) " +
				"select distinct mdcoar,mdalma,0,'00' from speed400tc.tmovd  a left outer join prodtecni.tsalmtemp  on mdalma=mdalmt and  mdcoar=mdcoat where mdalmt is null and a.mdejer=? and a.mdperi=?");
		pstm3.setInt(1, Integer.parseInt(ejercicio));
		pstm3.setInt(2, Integer.parseInt(periodo));
		pstm3.executeUpdate();
		pstm3.close();
		
		PreparedStatement pstm4 = Conexion.obtenerConexion().prepareStatement("select mdalmt,mdcoat,mdcant from prodtecni.tsalmtemp where MDSITU='00'");
		ResultSet rs = pstm4.executeQuery();
		while(rs.next()){
			String mdalmt = rs.getString("mdalmt");
			String mdcoat = rs.getString("mdcoat");
			double mdcant = rs.getDouble("mdcant");
			verificarNegativos(mdalmt,mdcoat,mdcant,ejercicio,periodo);
		}
		rs.close();
		pstm4.close();
	}

	private void verificarNegativos(String mdalmt, String mdcoat, double mdcant,String ejercicio,String periodo ) throws SQLException {
		PreparedStatement pstm = Conexion.obtenerConexion().prepareStatement("" +
				"select mdcmov,mdcanr,mdfech from speed400tc.tmovd where mdalma=? and mdcoar=? and mdejer=? and mdperi=? order by mdfech");
		pstm.setString(1, mdalmt);
		pstm.setString(2, mdcoat);
		pstm.setInt(3, Integer.parseInt(ejercicio));
		pstm.setInt(4, Integer.parseInt(periodo));
		ResultSet rs = pstm.executeQuery();
		while(rs.next()){
			String mdcmov = rs.getString("mdcmov");
			double mdcanr = rs.getDouble("mdcanr");
			int mdfech = rs.getInt("mdfech");
			if (mdcmov.equals("I")) {
				mdcant += mdcanr;
			} else {
				mdcant -= mdcanr;
			}
			if (mdcant < 0) {
				String mddesc="";
				String mddfam="";
				String mddsfa="";
				PreparedStatement pstm2 = Conexion.obtenerConexion().prepareStatement("select artdes,(select desesp from speed400tc.ttabd where tbiden='INFAM' and tbespe=artfam ) artfam,(select desesp from speed400tc.ttabd where tbiden='INSFA' and tbespe=artfam||artsfa ) artsfa  from speed400tc.tarti where artcod=?");
				pstm2.setString(1, mdcoat);
				ResultSet rs2 = pstm2.executeQuery();
				while(rs2.next()){
					mddesc = rs2.getString("artdes");
					mddfam = rs2.getString("artfam");
					mddsfa = rs2.getString("artsfa");
				}
				rs2.close();
				pstm2.close();
				
				registrarNegativo(mdalmt,mdcoat,mdcant,mdfech,ejercicio,periodo,mddesc.trim(),mddfam.trim(),mddsfa.trim());
			}
		}
		rs.close();
		pstm.close();
	}

	private void registrarNegativo(String mdalmt, String mdcoat, double mdcant,int mdfech, String ejercicio, String periodo,String mddesc,String mddfam,String mddsfa) throws SQLException {
		PreparedStatement pstm = Conexion.obtenerConexion().prepareStatement("insert into prodtecni.tsalmtemp(mdalmt,mdcoat,mdcant,mdfech,mdejer,mdperi,mdsitu,mddesc,mddfam,mddsfa) values (?,?,?,?,?,?,?,?,?,?)");
		pstm.setString(1, mdalmt);
		pstm.setString(2, mdcoat);
		pstm.setDouble(3, mdcant);
		pstm.setInt(4, mdfech);
		pstm.setInt(5, Integer.parseInt(ejercicio));
		pstm.setInt(6, Integer.parseInt(periodo));
		pstm.setString(7, "01");
		pstm.setString(8, mddesc);
		pstm.setString(9, mddfam);
		pstm.setString(10, mddsfa);
		pstm.executeUpdate();
		pstm.close();
	}

	private void exportar() throws SQLException {
		try {
			File destino = Sesion.elegirDestino();
			if(destino!=null){
				JasperReport reporte = (JasperReport) JRLoader
					.loadObject(ClassLoader
							.getSystemResource("reporte/Negativos.jasper"));
				Map<String, Object> parametros = new HashMap<String, Object>();
				parametros.clear();
				parametros.put(JRParameter.REPORT_LOCALE, Locale.US);
				JasperPrint jpLetras = JasperFillManager.fillReport(reporte,parametros,Conexion.obtenerConexion());
				JRXlsxExporter exporter = new JRXlsxExporter();
				exporter.setParameter(JRXlsExporterParameter.JASPER_PRINT,jpLetras); 
				exporter.setParameter(JRXlsExporterParameter.OUTPUT_FILE, new File(destino.toString() + ".xlsx"));
				exporter.setParameter(JRXlsExporterParameter.IS_ONE_PAGE_PER_SHEET,Boolean.FALSE);
				exporter.setParameter(JRXlsExporterParameter.IS_REMOVE_EMPTY_SPACE_BETWEEN_COLUMNS,Boolean.TRUE);
				exporter.setParameter(JRXlsExporterParameter.IS_REMOVE_EMPTY_SPACE_BETWEEN_ROWS,Boolean.TRUE);
				exporter.setParameter(JRXlsExporterParameter.IS_WHITE_PAGE_BACKGROUND,Boolean.FALSE);
				exporter.exportReport();
				Sesion.mensajeInformacion(null, "Su reporte de ha generado correctamente en la siguiente  ruta:\n"+destino.toString()+".xlsx");
			}
		} catch (JRException e) {
			Sesion.mensajeError(null,"JRException: " + e.getMessage() + " " + e.getCause());
		} catch (ArrayIndexOutOfBoundsException e) {
			Sesion.mensajeError(null,"ArrayIndexOutOfBoundsException: " + e.getMessage() + " " + e.getCause());
		} catch (Exception e) {
			Sesion.mensajeError(null,"Exception: " + e.getMessage() + " " + e.getCause());
		}				
	}	
}